// DialogConfiguration_Nano112.cpp : implementation file
//

#include "stdafx.h"
#include <deque>
#include <string>
#include <utility>
#include "ChipDefs.h"
#include "NumEdit.h"
#include "AppConfig.h"
#include "DialogConfiguration_Nano112.h"
#include <cassert>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDialogConfiguration_Nano112 dialog

CDialogConfiguration_Nano112::CDialogConfiguration_Nano112(unsigned int uProgramMemorySize,
        CWnd *pParent /*=NULL*/)
    : CDialogResize(CDialogConfiguration_Nano112::IDD, pParent)
    , m_uProgramMemorySize(uProgramMemorySize)
{
    //{{AFX_DATA_INIT(CDialogConfiguration_Nano112)
    m_nRadioClk = -1;
    m_nRadioBor = -1;
    m_nRadioBS = -1;
    m_nRadioHXT = -1;
    m_sConfigValue0 = _T("");
    m_sConfigValue1 = _T("");
    m_bClockFilterEnable = FALSE;
    m_bDataFlashEnable = FALSE;
    m_bSecurityLock = FALSE;
    m_sFlashBaseAddress = _T("");
    m_bWDTEnable = FALSE;
    //}}AFX_DATA_INIT
}

void CDialogConfiguration_Nano112::DoDataExchange(CDataExchange *pDX)
{
    CDialogResize::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CDialogConfiguration_Nano112)
    DDX_Control(pDX, IDC_EDIT_FLASH_BASE_ADDRESS, m_FlashBaseAddress);
    DDX_Control(pDX, IDC_EDIT_DATA_FLASH_SIZE, m_DataFlashSize);
    DDX_Control(pDX, IDC_SPIN_DATA_FLASH_SIZE, m_SpinDataFlashSize);
    DDX_Radio(pDX, IDC_RADIO_CLK_E12M, m_nRadioClk);
    DDX_Radio(pDX, IDC_RADIO_BOV_DISABLE, m_nRadioBor);
    DDX_Radio(pDX, IDC_RADIO_HXT_H16, m_nRadioHXT);
    DDX_Radio(pDX, IDC_RADIO_BS_LDROM, m_nRadioBS);
    DDX_Text(pDX, IDC_STATIC_CONFIG_VALUE_0, m_sConfigValue0);
    DDX_Text(pDX, IDC_STATIC_CONFIG_VALUE_1, m_sConfigValue1);
    DDX_Check(pDX, IDC_CHECK_CLOCK_FILTER_ENABLE, m_bClockFilterEnable);
    DDX_Check(pDX, IDC_CHECK_DATA_FLASH_ENABLE, m_bDataFlashEnable);
    DDX_Check(pDX, IDC_CHECK_SECURITY_LOCK, m_bSecurityLock);
    DDX_Text(pDX, IDC_EDIT_FLASH_BASE_ADDRESS, m_sFlashBaseAddress);
    DDX_Check(pDX, IDC_CHECK_WDT_ENABLE, m_bWDTEnable);
    DDX_Text(pDX, IDC_EDIT_DATA_FLASH_SIZE, m_sDataFlashSize);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDialogConfiguration_Nano112, CDialog)
    //{{AFX_MSG_MAP(CDialogConfiguration_Nano112)
    ON_BN_CLICKED(IDC_RADIO_CLK_E12M, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BS_LDROM, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_BROWN_OUT_DETECT, OnButtonClick)
    ON_EN_CHANGE(IDC_EDIT_FLASH_BASE_ADDRESS, OnChangeEditFlashBaseAddress)

    ON_BN_CLICKED(IDC_RADIO_BOV_DISABLE, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BOV_0, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BOV_1, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BOV_2, OnButtonClick)

    ON_BN_CLICKED(IDC_RADIO_CLK_I22M, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BS_APROM, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_BROWN_OUT_RESET, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_CLOCK_FILTER_ENABLE, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_DATA_FLASH_ENABLE, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_SECURITY_LOCK, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BS_LDROM_APROM, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_BS_APROM_LDROM, OnButtonClick)
    ON_BN_CLICKED(IDC_CHECK_WDT_ENABLE, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_HXT_H16, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_HXT_12_16, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_HXT_8_12, OnButtonClick)
    ON_BN_CLICKED(IDC_RADIO_HXT_L8, OnButtonClick)
    ON_WM_SIZE()
    ON_WM_VSCROLL()
    ON_WM_HSCROLL()
    ON_WM_GETMINMAXINFO()
    ON_WM_MOUSEWHEEL()
    ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DATA_FLASH_SIZE, OnDeltaposSpinDataFlashSize)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDialogConfiguration_Nano112 message handlers

BOOL CDialogConfiguration_Nano112::OnInitDialog()
{
    CDialog::OnInitDialog();
    // TODO: Add extra initialization here
    UDACCEL pAccel[1];
    pAccel[0].nInc = 1;
    pAccel[0].nSec = 0;
    m_SpinDataFlashSize.SetAccel(1, pAccel);
    ConfigToGUI();
    UpdateData(FALSE);
    m_bIsInitialized = true;
    GetWindowRect(m_rect);
    AdjustDPI();
    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

void CDialogConfiguration_Nano112::ConfigToGUI()
{
    unsigned int uConfig0 = m_ConfigValue.m_value[0];
    unsigned int uConfig1 = m_ConfigValue.m_value[1];

    switch (uConfig0 & NANO100_FLASH_CONFIG_CFOSC) {
        case NANO100_FLASH_CONFIG_E12M:
            m_nRadioClk = 0;
            break;

        case NANO100_FLASH_CONFIG_I12M:
        default:
            m_nRadioClk = 1;
            break;
    }

    switch (uConfig0 & NANO100_FLASH_CONFIG_CBORST) {
        case NANO100_FLASH_CONFIG_CBORST_RESERVED:
            m_nRadioBor = 0;
            break;

        case NANO100_FLASH_CONFIG_CBORST_25:
            m_nRadioBor = 1;
            break;

        case NANO100_FLASH_CONFIG_CBORST_20:
            m_nRadioBor = 2;
            break;

        case NANO100_FLASH_CONFIG_CBORST_17:
        default:
            m_nRadioBor = 3;
            break;
    }

    switch (uConfig0 & NANO100_FLASH_CONFIG_CBS) {
        case NANO100_FLASH_CONFIG_CBS_LD:
            m_nRadioBS = 0;
            break;

        case NANO100_FLASH_CONFIG_CBS_AP:
            m_nRadioBS = 1;
            break;

        case NANO100_FLASH_CONFIG_CBS_LD_AP:
            m_nRadioBS = 2;
            break;

        case NANO100_FLASH_CONFIG_CBS_AP_LD:
        default:
            m_nRadioBS = 3;
            break;
    }

    switch (uConfig0 & NANO100_FLASH_CONFIG_HXT_GAIN) {
        case NANO100_FLASH_CONFIG_HXT_RESERVED:
            m_nRadioHXT = -1;
            break;

        case NANO100_FLASH_CONFIG_HXT_H16:
            m_nRadioHXT = 0;
            break;

        case NANO100_FLASH_CONFIG_HXT_12_16:
            m_nRadioHXT = 1;
            break;

        case NANO100_FLASH_CONFIG_HXT_8_12:
            m_nRadioHXT = 2;
            break;

        case NANO100_FLASH_CONFIG_HXT_L8:
            m_nRadioHXT = 3;
            break;

        default:
            m_nRadioHXT = 1;
            break;
    }

    m_bClockFilterEnable = ((uConfig0 & NANO100_FLASH_CONFIG_CKF) == NANO100_FLASH_CONFIG_CKF ? TRUE : FALSE);
    m_bDataFlashEnable = ((uConfig0 & NANO100_FLASH_CONFIG_DFEN) == 0 ? TRUE : FALSE);
    m_bWDTEnable = ((uConfig0 & NANO100_FLASH_CONFIG_CWDTEN) == 0 ? TRUE : FALSE);;
    m_bSecurityLock = ((uConfig0 & NANO100_FLASH_CONFIG_LOCK) == 0 ? TRUE : FALSE);
    unsigned int uFlashBaseAddress = uConfig1;
    m_sFlashBaseAddress.Format(_T("%X"), uFlashBaseAddress);
    unsigned int uPageNum = uFlashBaseAddress / NANO100_FLASH_PAGE_SIZE;
    unsigned int uLimitNum = m_uProgramMemorySize / NANO100_FLASH_PAGE_SIZE;
    unsigned int uDataFlashSize = (uPageNum < uLimitNum) ? ((uLimitNum - uPageNum) * NANO100_FLASH_PAGE_SIZE) : 0;
    m_sDataFlashSize.Format(_T("%.2fK"), (m_bDataFlashEnable ? uDataFlashSize : 0) / 1024.);
    m_SpinDataFlashSize.EnableWindow(m_bDataFlashEnable ? TRUE : FALSE);
    m_sConfigValue0.Format(_T("0x%08X"), uConfig0);
    m_sConfigValue1.Format(_T("0x%08X"), uConfig1);
}

void CDialogConfiguration_Nano112::GUIToConfig()
{
    unsigned int uConfig0 = 0xFFFFFFFF;
    unsigned int uConfig1;
    uConfig0 &= ~NANO100_FLASH_CONFIG_CFOSC;

    switch (m_nRadioClk) {
        case 0:
            uConfig0 |= NANO100_FLASH_CONFIG_E12M;
            break;

        case 1:
            uConfig0 |= NANO100_FLASH_CONFIG_I12M;	/* New spec! */
            break;

        default:
            /* Keep old value */
            uConfig0 |= (m_ConfigValue.m_value[0] & NANO100_FLASH_CONFIG_CFOSC);
    }

    uConfig0 &= ~NANO100_FLASH_CONFIG_CBS;

    switch (m_nRadioBS) {
        case 0:
            uConfig0 |= NANO100_FLASH_CONFIG_CBS_LD;
            break;

        case 1:
            uConfig0 |= NANO100_FLASH_CONFIG_CBS_AP;
            break;

        case 2:
            uConfig0 |= NANO100_FLASH_CONFIG_CBS_LD_AP;
            break;

        case 3:
            uConfig0 |= NANO100_FLASH_CONFIG_CBS_AP_LD;
            break;

        default:
            /* Keep old value */
            uConfig0 |= (m_ConfigValue.m_value[0] & NANO100_FLASH_CONFIG_CBS);
    }

    uConfig0 &= ~NANO100_FLASH_CONFIG_CBORST;

    switch (m_nRadioBor) {
        case 0:
            uConfig0 |= NANO100_FLASH_CONFIG_CBORST_RESERVED;
            break;

        case 1:
            uConfig0 |= NANO100_FLASH_CONFIG_CBORST_25;
            break;

        case 2:
            uConfig0 |= NANO100_FLASH_CONFIG_CBORST_20;
            break;

        case 3:
            uConfig0 |= NANO100_FLASH_CONFIG_CBORST_17;
            break;

        default:
            /* Keep old value */
            uConfig0 |= (m_ConfigValue.m_value[0] & NANO100_FLASH_CONFIG_CBORST);
    }

    uConfig0 &= ~NANO100_FLASH_CONFIG_HXT_GAIN;

    switch (m_nRadioHXT) {
        case 0:
            uConfig0 |= NANO100_FLASH_CONFIG_HXT_H16;
            break;

        case 1:
            uConfig0 |= NANO100_FLASH_CONFIG_HXT_12_16;
            break;

        case 2:
            uConfig0 |= NANO100_FLASH_CONFIG_HXT_8_12;
            break;

        case 3:
            uConfig0 |= NANO100_FLASH_CONFIG_HXT_L8;
            break;

        //case -1: break;
        default:
            /* Keep old value */
            uConfig0 |= (m_ConfigValue.m_value[0] & NANO100_FLASH_CONFIG_HXT_GAIN);
    }

    if (false && m_bWDTEnable) { //disable CWDTEN
        uConfig0 &= ~NANO100_FLASH_CONFIG_CWDTEN;
    } else {
        uConfig0 |= NANO100_FLASH_CONFIG_CWDTEN;
    }

    if (m_bClockFilterEnable) {
        uConfig0 |= NANO100_FLASH_CONFIG_CKF;
    } else {
        uConfig0 &= ~NANO100_FLASH_CONFIG_CKF;
    }

    //if((m_bDataFlashEnable)&&(m_nRadioBS==1))		//2013 0521
    if (m_bDataFlashEnable) {
        uConfig0 &= ~NANO100_FLASH_CONFIG_DFEN;
    } else {
        uConfig0 |= NANO100_FLASH_CONFIG_DFEN;
    }

    if (m_bSecurityLock) {
        uConfig0 &= ~NANO100_FLASH_CONFIG_LOCK;
    } else {
        uConfig0 |= NANO100_FLASH_CONFIG_LOCK;
    }

    m_ConfigValue.m_value[0] = uConfig0;
    TCHAR *pEnd;
    uConfig1 = ::_tcstoul(m_sFlashBaseAddress, &pEnd, 16);
    m_ConfigValue.m_value[1] = uConfig1;
}

void CDialogConfiguration_Nano112::OnButtonClick()
{
    // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    GUIToConfig();
    ConfigToGUI();
    UpdateData(FALSE);
}

void CDialogConfiguration_Nano112::OnChangeEditFlashBaseAddress()
{
    // TODO: If this is a RICHEDIT control, the control will not
    // send this notification unless you override the CDialog::OnInitDialog()
    // function and call CRichEditCtrl().SetEventMask()
    // with the ENM_CHANGE flag ORed into the mask.
    // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    TCHAR *pEnd;
    unsigned int uFlashBaseAddress = ::_tcstoul(m_sFlashBaseAddress, &pEnd, 16);
    m_sConfigValue1.Format(_T("0x%08X"), uFlashBaseAddress);
    unsigned int uPageNum = uFlashBaseAddress / NANO100_FLASH_PAGE_SIZE;
    unsigned int uLimitNum = m_uProgramMemorySize / NANO100_FLASH_PAGE_SIZE;
    unsigned int uDataFlashSize = (uPageNum < uLimitNum) ? ((uLimitNum - uPageNum) * NANO100_FLASH_PAGE_SIZE) : 0;
    m_sDataFlashSize.Format(_T("%.2fK"), (m_bDataFlashEnable ? uDataFlashSize : 0) / 1024.);
    UpdateData(FALSE);
}

void CDialogConfiguration_Nano112::OnOK()
{
    // TODO: Add extra validation here
    UpdateData(TRUE);
    GUIToConfig();
    CDialog::OnOK();
}

void CDialogConfiguration_Nano112::OnDeltaposSpinDataFlashSize(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
    // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    TCHAR *pEnd;
    unsigned int uFlashBaseAddress = ::_tcstoul(m_sFlashBaseAddress, &pEnd, 16);
    unsigned int uPageNum = uFlashBaseAddress / NANO100_FLASH_PAGE_SIZE;
    unsigned int uLimitNum = m_uProgramMemorySize / NANO100_FLASH_PAGE_SIZE;

    if (pNMUpDown->iDelta == 1) {
        uPageNum += 1;
    } else if (pNMUpDown->iDelta == -1 && uPageNum > 0) {
        uPageNum -= 1;
    }

    uFlashBaseAddress = 0 + min(uPageNum, uLimitNum) * NANO100_FLASH_PAGE_SIZE;
    m_sFlashBaseAddress.Format(_T("%X"), uFlashBaseAddress);
    m_sConfigValue1.Format(_T("0x%08X"), uFlashBaseAddress);
    unsigned int uDataFlashSize = (uPageNum < uLimitNum) ? ((uLimitNum - uPageNum) * NANO100_FLASH_PAGE_SIZE) : 0;
    m_sDataFlashSize.Format(_T("%.2fK"), (m_bDataFlashEnable ? uDataFlashSize : 0) / 1024.);
    UpdateData(FALSE);
    *pResult = 0;
}

void CDialogConfiguration_Nano112::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar)
{
    if (pScrollBar != NULL && pScrollBar->GetDlgCtrlID() == m_SpinDataFlashSize.GetDlgCtrlID()) {
        return;
    }

    CDialogResize::OnVScroll(nSBCode, nPos, pScrollBar);
}
